Skip to content

chore: eliminate sys.path.insert hacks — migrate to package-relative imports#272

Closed
sheepdestroyer wants to merge 6 commits into
masterfrom
chore/eliminate-sys-path-hacks-565508234636993796
Closed

chore: eliminate sys.path.insert hacks — migrate to package-relative imports#272
sheepdestroyer wants to merge 6 commits into
masterfrom
chore/eliminate-sys-path-hacks-565508234636993796

Conversation

@sheepdestroyer

Copy link
Copy Markdown
Owner

What

This PR removes vestigial sys.path.insert hacks from scripts in scripts/, migrating to standard package-relative imports with ImportError fallbacks. It also adds a missing __init__.py to the router/ directory, normalizes structured content parsing in chat_helpers.py, and fixes direct script execution after Gemini Code Assist review exposed latent import failures.

Fixes #266

Changes since PR #271 (now closed)

ImportError fallbacks (9 scripts — Gemini Code Assist review fix):
When Python runs a script directly, it REPLACES sys.path[0] (the CWD) with the script's directory — so cross-package imports fail. Two patterns fixed:

  1. Scripts in scripts/ importing scripts.chat_helpers: try/except with bare from chat_helpers fallback (found in sys.path[0])
  2. Scripts in scripts/verification/ importing scripts.chat_helpers or router.*: try/except with sys.path.insert to repo root (parents[2])

Verified: all 9 scripts run successfully via both python scripts/X.py (direct) and package imports.

Original PR #271 changes (preserved)

Import cleanup (9 scripts)

  • Removed sys.path.insert hacks from all scripts in scripts/ and verification/
  • Replaced with from scripts.chat_helpers import parse_chat_response + ImportError fallback
  • Added try/except ImportError pattern to all scripts — ensures they remain runnable via both python scripts/foo.py (direct) and package imports

Router package

  • Added router/__init__.py to make router a proper Python package
  • Updated router/main.py to use from router.circuit_breaker import get_breaker (package-aware absolute import)
  • Note: relative import from .circuit_breaker was tested but reverted — it fails when test modules import main.py directly via from main import ... with PYTHONPATH=.:router

chat_helpers.py

  • Added _normalize_chat_content() helper that handles structured content payloads from alt providers (lists of dicts, nested content, etc.)
  • Updated parse_chat_response() to use the new normalizer for both content and reasoning_content

upgrade-prod.sh

  • Self-copy guard: re-execs from /tmp so rsync can safely update the script itself
  • Centralized cleanup via trap
  • Non-interactive mode support (auto-proceeds in CI/cron)
  • Pre-flight .env validation
  • Split rsync into individual safe calls per directory

Misc

  • Removed unused imports (asyncio, time) from test files

Previously PR #271 — closed and reopened with review fixes applied.

google-labs-jules Bot and others added 5 commits July 12, 2026 14:04
Co-authored-by: sheepdestroyer <1377479+sheepdestroyer@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
- Revert 'from .circuit_breaker' to 'from router.circuit_breaker' in main.py:
  relative imports break when main.py is imported directly as 'main'
  (tests use 'from main import ...' with PYTHONPATH=.:router)
- Add try/except ImportError fallback to 'from scripts.chat_helpers'
  across all 7 scripts (4 in scripts/, 3 in verification/)
  so they remain runnable via both package import and direct execution
…e imports

This commit:
- Removes sys.path.insert hacks from scripts/
- Adds router/__init__.py to make router a package
- Updates router/main.py and router/agy_proxy.py to use package-aware imports
- Updates tests and mocks to use absolute package paths
- Updates CI workflow to use standard PYTHONPATH=.
- Ensures both CLI and package execution modes work correctly

Co-authored-by: sheepdestroyer <1377479+sheepdestroyer@users.noreply.github.com>
Gemini Code Assist correctly identified that the PR's removal of sys.path
hacks broke direct execution of all 9 scripts. When Python runs a script,
it REPLACES sys.path[0] (the CWD) with the script's directory — so cross-
package imports (router.*, scripts.chat_helpers) fail with ModuleNotFoundError.

Two failure patterns, two fixes:

1. Scripts in scripts/ importing scripts.chat_helpers:
   try/except with bare 'from chat_helpers' fallback (found in sys.path[0])

2. Scripts in scripts/verification/ importing scripts.chat_helpers or router.*:
   try/except with sys.path.insert to repo root (parents[2])

Verified: all 9 scripts now run successfully via both 'python scripts/X.py'
(direct) and package imports (from scripts.X import ...)

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @sheepdestroyer, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@sheepdestroyer, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 46 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a1e4617-fb03-4270-ad83-8f21c4ee5a07

📥 Commits

Reviewing files that changed from the base of the PR and between 3f7f503 and 23d196b.

📒 Files selected for processing (22)
  • .github/workflows/test.yml
  • router/__init__.py
  • router/agy_proxy.py
  • router/main.py
  • router/tests/test_dashboard_data.py
  • router/tests/test_detect_active_tool.py
  • router/tests/test_estimate_prompt_tokens.py
  • router/tests/test_get_gemini_oauth_status.py
  • router/tests/test_get_goose_sessions.py
  • router/tests/test_load_persisted_stats.py
  • router/tests/test_resolve_external_urls.py
  • scripts/benchmark_classifier.py
  • scripts/benchmark_tokens.py
  • scripts/classify_direct.py
  • scripts/reclassify_all.py
  • scripts/retry_errors.py
  • scripts/verification/verification_helpers.py
  • scripts/verification/verify_breaker.py
  • scripts/verification/verify_canonical_endpoints.py
  • scripts/verification/verify_ollama_routing.py
  • tests/test_a2_verify.py
  • tests/test_models_proxy.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/eliminate-sys-path-hacks-565508234636993796

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors imports across the codebase to use absolute package imports (e.g., prefixing with router.) and adds fallback mechanisms for script imports. The feedback recommends removing obsolete sys.path manipulation hacks in router/tests/test_dashboard_data.py and router/tests/test_resolve_external_urls.py that are no longer needed now that absolute package imports are used.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread router/tests/test_dashboard_data.py Outdated
Comment on lines +10 to +13
if router_path not in sys.path:
sys.path.insert(0, router_path)

import main
from router import main

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since the import has been migrated to the absolute package import from router import main, the sys.path.insert hack is no longer necessary. For package imports to resolve, Python looks at the parent directory of the package (the repository root), which is already automatically included in sys.path by the test runner (pytest). Adding router_path (which points to repo/router) to sys.path does not help resolve from router import main because the router package is not located inside the router directory itself. Removing this redundant block simplifies the code and aligns with the PR's goal of eliminating path insertion hacks. Note that the unused router_path variable on line 9 and the comment on line 8 can also be safely removed.

    from router import main

Comment on lines +8 to +12
if router_path not in sys.path:
sys.path.insert(0, router_path)

import main
from main import resolve_external_urls
from router import main
from router.main import resolve_external_urls

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since the imports have been migrated to absolute package imports (from router import main and from router.main import resolve_external_urls), the sys.path.insert hack is no longer necessary. For package imports to resolve, Python looks at the parent directory of the package (the repository root), which is already automatically included in sys.path by the test runner (pytest). Adding router_path (which points to repo/router) to sys.path does not help resolve from router import main because the router package is not located inside the router directory itself. Removing this redundant block simplifies the code and aligns with the PR's goal of eliminating path insertion hacks. Note that the unused router_path variable on line 7 and the comment on line 6 can also be safely removed.

Suggested change
if router_path not in sys.path:
sys.path.insert(0, router_path)
import main
from main import resolve_external_urls
from router import main
from router.main import resolve_external_urls
from router import main
from router.main import resolve_external_urls

Gemini Code Assist flagged that test_dashboard_data.py and
test_resolve_external_urls.py still use sys.path.insert(0, router_path)
hacks despite having migrated to absolute package imports
(from router import main).

These hacks were doubly broken:
1. They inserted router/ (the package dir) into sys.path, which doesn't
   help resolve 'from router import main' — Python needs the PARENT dir.
2. router/tests/conftest.py already inserts the correct dir (repo root).

Removed the dead sys/os imports along with the hack blocks.
All 193 tests pass. Scripts import cleanly.
@sheepdestroyer

Copy link
Copy Markdown
Owner Author

Closing in favor of a fresh PR with Gemini Code Assist review fixes applied. See #<new_PR>.

@sheepdestroyer

Copy link
Copy Markdown
Owner Author

Closed in favor of a fresh PR with all Gemini Code Assist review fixes applied. See #273.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: eliminate sys.path.insert hacks — migrate to package-relative imports

1 participant